package indi.zhifa.recipe.bailan.framework.auth.service.impl;
import indi.zhifa.recipe.bailan.framework.auth.dao.IBaseAuthNodeRelevantDao;
import indi.zhifa.recipe.bailan.framework.auth.dao.IBaseUserRelevantDao;
import indi.zhifa.recipe.bailan.framework.auth.entity.po.*;
import indi.zhifa.recipe.bailan.framework.auth.service.IBaseUserAuthService;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RequiredArgsConstructor
public abstract class BaseUserAuthServiceImpl implements IBaseUserAuthService {

    private final IBaseAuthNodeRelevantDao mDepartmentRelevantDao;
    private final IBaseUserRelevantDao mUserRelevantDao;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void changeDepartment(Long pUserId, Long pDomainId, Long pDepartmentId) {
        List<BaseRelUserAuthEntity> baseRelUserAuthEntityList = mDepartmentRelevantDao.relUserAuth_listByUserId(pUserId);
        BaseAuthNodeEntity baseAuthNodeEntity = null;
        if(null != pDepartmentId){
            baseAuthNodeEntity = mDepartmentRelevantDao.authNode_check(pDepartmentId);
        }
        Map<Long, BaseRelUserAuthEntity> baseRelUserDepEntityMapByDomain = baseRelUserAuthEntityList.stream().collect(Collectors.toMap(BaseRelUserAuthEntity::getDomainId, baseRelUserDepEntity -> baseRelUserDepEntity));
        if(baseRelUserDepEntityMapByDomain.containsKey(pDomainId)){
            BaseRelUserAuthEntity curRelUserDep = baseRelUserDepEntityMapByDomain.get(pDomainId);
            if(null == pDepartmentId){
                baseRelUserDepEntityMapByDomain.remove(pDomainId);
            }else{
                curRelUserDep.setAuthId(baseAuthNodeEntity.getId());
                curRelUserDep.setAuthCode(baseAuthNodeEntity.getCode());
                curRelUserDep.setAuthCascade(baseAuthNodeEntity.getCascade());
            }
        }
        mDepartmentRelevantDao.relUserAuth_deleteByUserId(pUserId);
        List<BaseRelUserAuthEntity> savingRelUserDepEntityList = new ArrayList<>(baseRelUserDepEntityMapByDomain.values());
        mDepartmentRelevantDao.relUserAuth_saveBatch(pUserId,savingRelUserDepEntityList);
    }

    @Override
    public List<BaseRelUserRoleEntity> baseAssignRolesWithCode(Long pUserId, List<String> pRoleCodes) {
        BaseUserEntity userEntity = mUserRelevantDao.user_check(pUserId);
        List<BaseRelUserRoleEntity> baseRelUserRoleEntityList = mUserRelevantDao.relUserRole_listByUserId(pUserId);
        Map<String,BaseRelUserRoleEntity> baseRelUserRoleEntityMap = baseRelUserRoleEntityList.stream().collect(
                Collectors.toMap(BaseRelUserRoleEntity::getRoleCode,baseRelUserRoleEntity -> baseRelUserRoleEntity));
        List<BaseRelUserRoleEntity> editingRelUserRoleEntityList = new ArrayList<>();
        for(String roleCode : pRoleCodes){
            BaseRoleEntity roleEntity = mUserRelevantDao.role_check(roleCode);
            if(baseRelUserRoleEntityMap.containsKey(roleCode)){
                editingRelUserRoleEntityList.add(baseRelUserRoleEntityMap.get(roleCode));
            }else{
                BaseRelUserRoleEntity newRole = mUserRelevantDao.relUserRole_generate();
                newRole.createInit();
                newRole.setUserId(pUserId);
                newRole.setUserName(userEntity.getName());
                newRole.setRoleId(roleEntity.getId());
                newRole.setRoleCode(roleEntity.getCode());
                editingRelUserRoleEntityList.add(newRole);
            }
        }
        mUserRelevantDao.relUserRole_updateRoles(pUserId,editingRelUserRoleEntityList);
        return editingRelUserRoleEntityList;
    }

    @Override
    public List<BaseRelUserRoleEntity> baseAssignRolesWithId(Long pUserId, List<Long> pRoleIds) {
        BaseUserEntity userEntity = mUserRelevantDao.user_check(pUserId);
        List<BaseRelUserRoleEntity> baseRelUserRoleEntityList = mUserRelevantDao.relUserRole_listByUserId(pUserId);
        Map<Long,BaseRelUserRoleEntity> baseRelUserRoleEntityMap = baseRelUserRoleEntityList.stream().collect(
                Collectors.toMap(BaseRelUserRoleEntity::getRoleId,baseRelUserRoleEntity -> baseRelUserRoleEntity));
        List<BaseRelUserRoleEntity> editingRelUserRoleEntityList = new ArrayList<>();
        for(Long roleId : pRoleIds){
            BaseRoleEntity roleEntity = mUserRelevantDao.role_check(roleId);
            if(baseRelUserRoleEntityMap.containsKey(roleId)){
                editingRelUserRoleEntityList.add(baseRelUserRoleEntityMap.get(roleId));
            }else{
                BaseRelUserRoleEntity newRole = mUserRelevantDao.relUserRole_generate();
                newRole.createInit();
                newRole.setUserId(pUserId);
                newRole.setUserName(userEntity.getName());
                newRole.setRoleId(roleEntity.getId());
                newRole.setRoleCode(roleEntity.getCode());
                editingRelUserRoleEntityList.add(newRole);
            }
        }
        mUserRelevantDao.relUserRole_updateRoles(pUserId,editingRelUserRoleEntityList);
        return editingRelUserRoleEntityList;
    }

}
